﻿using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace TestConsole
{
	static class Program
	{
		static Dictionary<DateTime, int> Reserves = new Dictionary<DateTime, int>();
		static void PutData(int y, int m, int d, int a)
		{
			Reserves.Add(new DateTime(y, m, d), a);
		}
		static void PutData()
		{
			PutData(2014, 6, 9, 265000);
			PutData(2014, 7, 3, 222700);
			PutData(2014, 8, 3, 222700);

			PutData(2014, 9, 2, 40000);
			PutData(2014, 10, 2, 40000);
			PutData(2014, 11, 2, 40000);
			PutData(2014, 12, 2, 40000);

			for (int i = 9; i < 13; i++)
			{
				PutData(2014, i, 1, 30000);
				PutData(2014, i, 8, 30000);
				PutData(2014, i, 15, 30000);
				PutData(2014, i, 22, 30000);
			}
		}
		public static int WeekOfYear(this DateTime T)
		{
			DateTime x = T;
			int res = 0;
			while (x.Year == T.Year)
			{
				x = x.Subtract(new TimeSpan(24 * 7, 0, 0));
				res++;
			}
			return res;
		}
		static void Main2(string[] args)
		{
			if (false)
			{
				String[] Rows = System.IO.File.ReadAllLines("c:\\Games\\Haegemonia\\Game_Inf\\Inventions\\WEAPON TECHNOLOGIES MISSILE WEAPON TECH.txt");
				foreach (var s in Rows)
				{
					string[] row = s.Split('\t');
					Console.WriteLine(row.Length);
					/*Console.WriteLine(row[0].PadRight(10)
						+ " " + row[1].PadRight(20)
						+ " " + row[2].PadRight(20)
						+ " " + row[3].PadRight(20)
						+ " " + row[4].PadRight(30) + " | " + row[36]);
					*/
				}
				Console.ReadKey(true);
				return;
			}
			PutData();
			int W = 0;
			DateTime end = DateTime.Today.AddDays(7);
			end = new DateTime(2014, 12, 31);
			for (DateTime T = new DateTime(2013, 12, 30); T < end; T = T.AddDays(7))
			{
				W++;
				int N = 0;
				foreach (var X in Reserves)
					if (X.Key < T)
						N += X.Value;
				int Trg = W * 25000;
				Console.WriteLine(T + " " + W.ToString("00") + " " + N.ToString().PadLeft(9) + " " + Trg.ToString().PadLeft(9) + "   " + (N * 100.0 / Trg).ToString("000.00") + "%");
			}
			Console.ReadKey(true);
		}

		static List<BetThread> Threads = new List<BetThread>();
		static int SelectedMenu = -1;

		static bool AskValue(ref float res, string msg = "")
		{
			if (msg != "")
				Console.WriteLine(msg);
			String S = Input("");
			try
			{
				if (S == "")
					return false;
				res = float.Parse(S);
				return true;
			}
			catch
			{
				return AskValue(ref res, "Invalid value");
			}
		}
		static String Input(string caption)
		{
			Console.Clear();
			Console.BackgroundColor = ConsoleColor.Gray;
			Console.ForegroundColor = ConsoleColor.Black;
			Console.WriteLine(" " + caption.PadRight(20) + " ");
			Console.Write(" ");
			Console.CursorLeft += 18;
			Console.WriteLine(" ");
			Console.WriteLine("".PadLeft(22));
			Console.ReadKey(true);
			return "";
		}
		static bool Menu()
		{
			Draw();
			ConsoleKey C = Console.ReadKey(true).Key;
			switch (C)
			{
				case ConsoleKey.UpArrow:
					SelectedMenu = (SelectedMenu + 24) % 25;
					break;
				case ConsoleKey.DownArrow:
					SelectedMenu = (SelectedMenu + 1) % 25;
					break;
				case ConsoleKey.C:
					if (SelectedMenu != -1)
					{
						Threads[SelectedMenu].Create(2500);
						Threads[SelectedMenu].CurrentAmount = 2600;
					}
					break;
				case ConsoleKey.Enter:
					if (SelectedMenu != -1)
					{
						float val = -1;
					}
					break;
				case ConsoleKey.X:
					return false;
			}
			return true;
		}
		static void Draw()
		{
			Console.Clear();
			for (int i = 0; i < 25; i++)
			{
				var t = Threads[i];
				if (i == SelectedMenu)
				{
					Console.ForegroundColor = ConsoleColor.Black;
					Console.BackgroundColor = ConsoleColor.Gray;
				}
				else
					Console.ResetColor();
				Console.WriteLine(t.ToString());
			}
		}
		static void Main3(string[] args)
		{
			for (int i = 0; i < 25; i++)
				Threads.Add(new BetThread(200));

			while (Menu())
				;
			//Console.ReadKey(true);
		}

		static string[] GetCityAddresses()
		{
			WebClient C = new WebClient();
			C.DownloadString("");
			return new string[] { "" };
		}
		static void Main4(string[] args)
		{

		}
		static void SweepArrayCap(ref int[] i)
		{
			for (int j = i.Length - 1; j > 0; j--)
			{
				if (i[j] > 2)
				{
					i[j - 1]++;
					i[j] = 0;
				}
			}
		}
		static void AcquireScores(int match, ref int T1, ref int T2)
		{
			if (match == 0)
				T1 += 3;
			else if (match == 2)
				T2 += 3;
			else
			{
				T1++;
				T2++;
			}
		}
		static List<String> Res = new List<string>();
		static void Main5(string[] args)
		{
			TimeSeries.WriteRow("res.txt", DateTime.Now, "name", 123.4);
			TimeSeries.WriteRow("res.txt", DateTime.Now, "name", 0.43, "*");
			Console.ReadKey(true);
			return;
			for (int[] i = { 0, 0, 0, 0, 0, 0 }; i[0] < 3; i[5]++, SweepArrayCap(ref i))
			{
				//Console.WriteLine(i[0] + "," + i[1] + "," + i[2] + "," + i[3]);

				int Team1 = 0, Team2 = 0, Team3 = 0, Team4 = 0;
				AcquireScores(i[0], ref Team1, ref Team2);
				AcquireScores(i[1], ref Team3, ref Team4);
				AcquireScores(i[2], ref Team1, ref Team3);
				AcquireScores(i[3], ref Team2, ref Team4);
				AcquireScores(i[4], ref Team1, ref Team4);
				AcquireScores(i[5], ref Team2, ref Team3);
				List<int> I = new List<int>();
				I.AddRange(new int[] { Team1, Team2, Team3, Team4 });
				I.Sort();
				String S = I[0] + "" + I[1] + "" + I[2] + "" + I[3];
				if (!Res.Contains(S))
				{
					Res.Add(S);
					Console.ForegroundColor = S[0] == S[1] || S[1] == S[2] || S[2] == S[3] ? ConsoleColor.Red : ConsoleColor.Gray;
					Console.WriteLine(S);
				}
			}
			//Permutator<StringPermutatorState> X = new Permutator<StringPermutatorState>();
			//X.Reset();
			Console.ReadKey(true);
		}

		//prime
		static void Main6(string[] args)
		{
			producttable table = new producttable();
			String N = "1522605027922533360535618378132637429718068114961380688657908494580122963258952897654000350692006139";
			//String N = "39601";
			table.FillResult(N);

			Console.WriteLine("Selected Number: " + N);
			table.Sqrt();
			table.Write1();
			//table.SearchReverse("res1.txt");
			N = "28";
			table.FillResult(N);
			Console.WriteLine("Selected Number: " + N);
			//table.SearchReverse("res2.txt");
			Console.ReadKey(true);
		}

		static void Main(string[] args)
		{
			c1 c = new c1();
			c.Add(1);
			c.Add(3);
			c.Add(2);
			c.write();
			Console.ReadKey(true);
		}
	}
	class i1
	{
		public int field;
		public i1(int f)
		{
			field = f;
		}
		public override string ToString()
		{
			return "I1: " + field;
		}
	}
	class i2 : i1
	{
		public i2(int f)
			: base(f)
		{
		}
		public override string ToString()
		{
			return "I2: " + field;
		}
	}
	class c1
	{
		public List<i1> items = new List<i1>();
		public c1()
		{
		}

		public void write()
		{
			foreach (var i in items)
			{
				Console.WriteLine(i.ToString());
			}
		}
		public void Add(int n)
		{
			items.Add(new i1(n));
		}
	}
	class c2 : c1
	{
		new public List<i2> items = new List<i2>();
		public c2()
		{
		}
	}

	class producttable
	{
		public short[] Digits1 = new short[0];
		public void Write1()
		{
			String S = "";
			for (int i = 0; i < Digits1.Length; i++)
				S += "" + Digits1[Digits1.Length - 1 - i];
			Console.WriteLine(S);
		}
		public int D1Ptr = 0;
		public short[] Digits2 = new short[0];
		public int D2Ptr = 0;
		public short[] Result = new short[0];
		public short[] NeedResult = new short[0];

		public short[,] Table1;
		public short[,] Table2;
		public bool CheckResult(int L = -1)
		{
			if (L == -1)
				L = Result.Length;
			for (int i = 0; i < L; i++)
			{
				if (NeedResult[i] != Result[i])
					return false;
			}
			for (int i = NeedResult.Length; i < Result.Length; i++)
				if (Result[i] != 0)
					return false;
			return true;
		}
		public void GenerateTable(bool fromresult)
		{
			if (fromresult)
			{
				Digits1 = new short[NeedResult.Length];
				Digits2 = new short[NeedResult.Length];
				Result = new short[NeedResult.Length * 2];
				for (int i = 0; i < Result.Length; i++)
					Result[i] = 0;
				for (int i = 0; i < NeedResult.Length; i++)
					Digits1[i] = Digits2[i] = 0;
				Table1 = new short[NeedResult.Length * 2, NeedResult.Length];
				Table2 = new short[NeedResult.Length * 2, NeedResult.Length];
			}
			else
			{
				int S = Digits1.Length + Digits2.Length;
				Table1 = new short[S, Digits2.Length];
				Table2 = new short[S, Digits2.Length];
				Result = new short[S];
			}
		}
		void Put1(short D)
		{
			Digits1[D1Ptr] = D;
			D1Ptr++;
		}
		void Del1()
		{
			D1Ptr--;
			Digits1[D1Ptr] = 0;
		}
		void Put2(short D)
		{
			Digits2[D2Ptr] = D;
			D2Ptr++;
		}
		void Del2()
		{
			D2Ptr--;
			Digits2[D2Ptr] = 0;
		}

		//Numbers stored in reverse order for better indexing
		void Fill(ref short[] buffer, String number)
		{
			buffer = new short[number.Length];
			for (int i = 0; i < number.Length; i++)
				buffer[number.Length - i - 1] = byte.Parse("" + number[i]);
		}
		public void FillNumber1(String number)
		{
			Fill(ref Digits1, number);
		}
		public void FillNumber2(String number)
		{
			Fill(ref Digits2, number);
		}
		public void FillResult(String number)
		{
			Fill(ref NeedResult, number);
		}

		public void ProcessTable()
		{
			for (int i = 0; i < Table1.GetLength(0); i++)
				for (int j = 0; j < Table1.GetLength(1); j++)
					Table1[i, j] = 0;
			for (int i = 0; i < D1Ptr; i++)
				for (int j = 0; j < D2Ptr; j++)
				{
					Table1[i + j, j] = (short)(Digits1[i] * Digits2[j]);
				}
			for (int i = 0; i < Result.Length; i++)
				Result[i] = 0;
			for (int i = 0; i < Result.Length; i++)
				for (int j = 0; j < Digits2.Length; j++)
				{
					Result[i] += Table1[i, j];
				}
			for (int i = 0; i < Result.Length - 1; i++)
			{
				Result[i + 1] += (short)(Result[i] / 10);
				Result[i] = (short)(Result[i] % 10);
			}
		}

		//-1: result is bigger
		// 1: needresult is bigger
		public int Compare()
		{
			if (Result.Length > NeedResult.Length)
			{
				for (int i = NeedResult.Length; i < Result.Length; i++)
					if (Result[i] != 0)
						return -1;
			}
			for (int i = 0; i < NeedResult.Length; i++)
			{
				if (NeedResult[NeedResult.Length - 1 - i] > Result[NeedResult.Length - 1 - i])
					return 1;
				if (NeedResult[NeedResult.Length - 1 - i] < Result[NeedResult.Length - 1 - i])
					return -1;
			}
			return 0;
		}
		public void Sqrt()
		{
			Result = new short[NeedResult.Length + 1];
			
			Digits1 = new short[(NeedResult.Length + 1) / 2];
			Digits2 = new short[(NeedResult.Length + 1) / 2];
			D1Ptr = D2Ptr = Digits1.Length;
			Table1 = new short[NeedResult.Length + 1, Digits2.Length];
			for (int i = 0; i < (NeedResult.Length + 1) / 2; i++)
				Digits1[i] = Digits2[i] = 0;
			MoveSqrt(Digits1.Length - 1);
		}
		bool MoveSqrt(int digit)
		{
			bool found = false;
			for (short i = 1; i < 10 && !found; i++)
			{
				Digits1[digit] = Digits2[digit] = i;
				ProcessTable();
				int CMP = Compare();
				if (CMP == 0)
					return true;
				else if (CMP == -1)
				{
					if (digit == 0)
						return true;
					Digits1[digit] = Digits2[digit] = (short)(i - 1);
					found = MoveSqrt(digit - 1);
				}
				else if (Digits1[digit] == 9)
				{
					found = MoveSqrt(digit - 1);
				}
			}
			return found;
		}
		DateTime searchtime;
		public int NRes = 0;
		TextWriter W;
		public void SearchReverse(string fn)
		{
			W = File.CreateText(fn);
			NRes = 0;
			GenerateTable(true);
			searchtime = DateTime.Now;
			MakeStep(0);
			W.Close();
		}

		//Assume Digit1 longer than Digit2

		void MakeStep(int Digits)
		{
			if (Digits == NeedResult.Length)
			{
				NRes++;
				String S = "";
				for (int i = 0; i < D1Ptr; i++)
					S += "" + Digits1[D1Ptr - 1 - i];
				W.WriteLine(S);
			}
			else
			{
				for (short i = 0; i < 10; i++)
				{
					for (short j = 0; j < 10; j++)
					{
						Put1(i);
						Put2(j);

						ProcessTable();
						int D1 = D1Ptr;
						while (D1 > 0 && Digits1[D1 - 1] == 0)
							D1--;
						int D2 = D1Ptr;
						while (D2 > 0 && Digits2[D2 - 1] == 0)
							D2--;
						if (CheckResult(Digits + 1) && D1 + D2 < NeedResult.Length + 3)
						{
							MakeStep(Digits + 1);
						}
						Del1();
						Del2();
					}
				}
			}
		}
	}

	class StringPermutatorState : PermutationState
	{
		public override void ResetState()
		{

		}
		public override void SetState(params object[] parameters)
		{
			throw new NotImplementedException();
		}
	}
	class BetThread
	{
		public double StartAmount;
		public double BaseOdds = 1.05f;
		public double CurrentAmount;
		public double Level
		{
			get
			{
				return Math.Log(CurrentAmount / StartAmount, BaseOdds);
			}
		}

		public void Create(double amount)
		{
			StartAmount = CurrentAmount = amount;
		}
		public BetThread(double start)
		{
			Create(start);
		}
		public override string ToString()
		{
			string Col1 = StartAmount.ToString("00000");
			string Col2 = CurrentAmount.ToString("00000");
			string Col3 = BaseOdds.ToString("0.00");
			double L = Math.Floor(Level);
			double CurrentBase = StartAmount * Math.Pow(BaseOdds, L);
			double NextBase = StartAmount * Math.Pow(BaseOdds, L + 1);

			return Col1 + " " + Col2 + " " + Col3 + " L" + L + " " + ((Level - L) * 100).ToString("000.00") + "% " + CurrentBase.ToString("00000") + " -> " + NextBase.ToString("00000");
		}
	}
}